package com.artemis.event;

import com.artemis.World;
import com.artemis.utils.Bag;

/**
 * Interface for event delivering.
 * an EventDeliveringSystem usually takes care about all {@link SystemEvent}s
 * that are posted into the world.
 * SystemEvents of a certain type can be polled via {@link #getEvents(int, Bag)}.
 * <br>
 * {@link World#postEvent(SystemEvent)}, {@link World#getEvents(int, Bag)} and
 * {@link World#getEvents(Class, Bag)} don't have any effect unless an EventDeliverySystem
 * is added to the world.
 * <br><br>
 * Inspired by apotapov's event system implementation of his gdx-artemis (see: http://github.com/apotapov/gdx-artemis)
 * 
 * @author kryo
 *
 * @see World#setEventDeliverySystem(EventDeliverySystem)
 */
public interface EventDeliverySystem {
	
	/**
	 * Initializes the system.
	 * If the World-instance has an EventDeliverySystem, it
	 * will automatically called on {@link World#initialize()}.
	 */
	public void initialize();
	
	/**
	 * Updates the system.
	 * It will automatically called at the end of {@link World#process()}.
	 */
	public void update();
	
	/**
	 * Posts a SystemEvent.
	 * 
	 * @param e the event that should posted.
	 */
	public void postEvent(SystemEvent e);
	
	/**
	 * Polls SystemEvents of certain type.
	 * 
	 * @param typeId the type of the event.
	 * @param events the buffer to put the events in.
	 */
	public <E extends SystemEvent> void getEvents(int typeId, Bag<E> events);
}